import re
from PyQt5 import QtCore
from PyQt5.QtWidgets import QWidget, QLabel, QVBoxLayout, QPushButton, QFileDialog, QTableWidget, \
    QTableWidgetItem
from PyQt5.QtCore import QThreadPool
import pandas as pd
import numpy as np
from utils.memoryUtil import PandasSharedMemory
from components.paged_table import PagedTable


class FaceManyView(QWidget):
    data = QtCore.pyqtSignal(list)
    reload_table_signal = QtCore.pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.titles = ['姓名', '证件号', '文件路径', '识别结果']
        self.label = QLabel("人脸批量录入")
        self.data = []
        # self.table = QTableWidget()
        self.table = PagedTable('face_input_many')
        self.threadpool = QThreadPool()
        self.layout = QVBoxLayout()

        # 连接信号到子控件的方法
        self.reload_table_signal.connect(self.table.init)
        self.init()

    def init(self):

        button_add = QPushButton("添加图片")
        button_add.clicked.connect(self.open_file)

        # self.table.setColumnCount(4)
        # self.table.setHorizontalHeaderLabels(self.titles)

        self.layout.addWidget(self.table)
        self.layout.addWidget(button_add)
        self.layout.addStretch()

        self.setLayout(self.layout)
        self.show()

    def open_file(self):
        """
        打开多张图片
        :return:
        """
        # 文件选择框
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        file_paths, _ = QFileDialog.getOpenFileNames(self, "选择图片", "/Desktop",
                                                     "图片文件 (*.png *.jpg *.jpeg *.gif *.bmp)")
        photos = []
        df = None
        if file_paths:
            # 生成pandas 数据
            for index, value in enumerate(file_paths):
                #  检查图片命名是否合规 【姓名_身份证】的格式
                data_name = ''
                data_id = ''
                result = value.split('/')
                file_path = result[len(result) - 1]
                pattern = re.compile(r'.*_.*')

                data_path = value
                if not pattern.match(result[len(result) - 1]):
                    data_verify = '文件名非法'
                else:
                    data_name = file_path.split('_')[0]
                    data_id = file_path.split('.')[0].split('_')[1]

                    verify_name = ''
                    if len(verify_name) > 0:
                        data_verify = '人脸录入成功'
                    else:
                        data_verify = '人脸录入失败'
                self.data.append({"姓名": data_name, "证件号": data_id, "文件路径": data_path, "识别结果": data_verify})
                if len(data_id) > 0:
                    photos.append({"name": data_name, "id": data_id, "path": data_path, "result": data_verify})
            df = pd.DataFrame(self.data)

        reader = PandasSharedMemory('face_input_many')
        read_dt = reader.read_dataframe()
        if read_dt is None:
            writer = PandasSharedMemory('face_input_many')
            writer.write_dataframe(df)
        else:
            # 读取示例
            modify = PandasSharedMemory('face_input_many')
            modify.modify_dataframe(df)
        self.emit_signal()

        # 调整所有列宽以适应内容
        self.table.resize_columns()
        # 启动多线程识别图片
        self.start(photos)

    def start(self, photos):
        from threads.face.FaceWorker import Worker
        base_thread = Worker(photos)
        base_thread.signals.result.connect(self.success)
        base_thread.signals.error.connect(self.error)
        base_thread.signals.finished.connect(self.task_finished)
        self.threadpool.start(base_thread)

    def success(self, value):
        """
        人脸识别成功的更新
        :param value: 证件号码，为空则表示失败, 非空表示识别成功
        :return:
        """
        reader = PandasSharedMemory('face_input_many')
        df = reader.read_dataframe()
        for index, line in enumerate(self.data):
            if value['key'] == line['证件号'] and value['result']:
                self.data[index]['识别结果'] = '人脸录入成功'
        # 再次更新内存数据
        df = pd.DataFrame(self.data)
        reader = PandasSharedMemory('face_input_many')
        read_dt = reader.read_dataframe()
        if read_dt is None:
            writer = PandasSharedMemory('face_input_many')
            writer.write_dataframe(df)
        else:
            # 读取示例
            modify = PandasSharedMemory('face_input_many')
            modify.modify_dataframe(df)
        self.emit_signal()


        # row_count = self.table.rowCount()
        # for row in range(row_count):
        #     # 获取当前行的所有单元格数据
        #     item = self.table.item(row, 1)
        #     if item is None:
        #         continue
        #     if item.text() == value['key'] and value['result']:
        #         self.table.setItem(row, 3, QTableWidgetItem('人脸录入成功'))
        # 调整所有列宽以适应内容
        # self.table.resizeColumnsToContents()

    def error(self, value):
        """
        人脸识别报错的函数，打印报错信息
        :param value:
        :return:
        """
        print(f'系统异常，请排查')

    @staticmethod
    def task_finished():
        print("任务完成")

    def emit_signal(self):
        self.reload_table_signal.emit('face_input_many')
